Lunar Lander

Table of Contents

Part 1 of this assignment is to be done individually. One you’ve got part 1 done, then get together with your partner to do part 2. Look at the code you’ve both written for part 1, and you can decide to use code from just one of you, or combine together. It’s your choice.

1. Get started

Create a folder in which to store your work for this assignment.

  • If you are working on your own computer, it’s up to you where to put the folder. Your desktop is likely as good a place as any. Make a folder titled lunarlander.
  • If you are working in the labs in Olin, make sure to first mount the COURSES folder, so that you won’t lose your code when you log out. Once you’ve done so, open up Finder, then navigate to your personal student work folder. You can then make a lunarlander folder within there.
  • Once you’ve done so, you should then open up your new folder in VS Code. To do so, start up VS Code, then drag your folder onto the VS Code window. This should open up the folder within VS Code. If you are asked, click that you trust the authors.

2. Overview

Computer simulation is used by engineers to test out ideas before actually building expensive machines or putting people in dangerous situations. Simulation is a critical part of the the space program by NASA, for example.

For this program, you will create a simulation of a vehicle landing on the moon. (It turns out that this assignment is also a rather old computer game that has been around for decades.)

Here is how it works: You are in control of a lunar lander ship, descending to the surface of the moon for a landing. Gravity steadily accelerates your ship faster and faster toward the surface of the moon. You, the astronaut piloting the ship, have a single control: a button with the label “thrust” on it. Applying thrust slows your ship down. Your goal is to get your ship to land on the moon at a slow enough speed so that it doesn’t crash on impact. What’s the catch? You have only a limited amount of fuel. If you slow down your ship too much too early, you will run out of fuel and crash into the surface of the moon.

Your mission: Program this simulation in Python.

3. Details

In your folder, create a file named lunarlander.py. In that file, you should create a LunarLander class, and also a main function. Your main function (and the line that calls it) should be the only code you write that should be outside of the LunarLander class. This class represents the ship itself. The main method controls how the simulation works. In your LunarLander class, you will need to keep the following information in instance variables:

  • altitude: how far the ship is from the surface of the moon, in meters. Initial value: 1000 meters.
  • velocity: how fast the ship is moving, in meters/second. A positive velocity means that that ship is moving toward the moon’s surface. A negative velocity means that the ship is moving away. Initial value: 40 meters/second.
  • fuel: how many units of fuel are left in the tank. Initial value: 25 units.

LunarLander should have the following methods (you may have more if you wish):

  • a constructor that initializes all your instance variables with the initial values provided above
  • getVelocity() returns the velocity your lander
  • getAltitude() returns the altitude of your lander
  • getFuel() returns the units of fuel left in your lander
  • thrust() applies one unit of fuel to give thrust to the ship (so it deducts 1 from your fuel), and decreases the velocity by 4 meters/sec
  • doOneSecond(fuelUnits) simulates one complete second of activity, where the astronaut has requested to burn fuelUnits units of fuel. Specifically, it should do the following:
    1. Make sure you check to see if you actually have this much fuel. If not, just burn all that you have in the steps below.
    2. Call the thrust() method repeatedly, once for each unit of fuel you plan to burn. thrust() will then deduct that unit of fuel, and adjust your velocity accordingly.
    3. Modify your velocity to add the effect of gravity, which adds an additional 2 meters/second.
    4. Determine the new altitude for your lander. Your new altitude is your old altitude minus your velocity after the above adjustments.

Your main function should create a LunarLander object, provide the player with a welcome message, then repeatedly show the player the current information for the lander followed by a question as to how many units of thrust to burn. If the lander ends up hitting the surface of the moon with a velocity of 4 meters/second or less, the ship lands successfully! If the lander hits the surface with a velocity of 5 meters/second or more, the ship crashes. You’ll find a sample game at the bottom of this assignment.

4. Parts 1 and 2

This assignment is broken into two parts to help you pace yourself. Part 1 should have at least:

  • LunarLander constructor, getVelocity, getAltitude, and getFuel methods
  • main that creates a LunarLander object, and uses its methods in some way (such as printing out altitude, velocity, and fuel to the screen)

Part 2 should, of course, finish the assignment. You are welcome to turn in more than the minimum for Part 1, including the complete assignment, at the first deadline if you like. The brunt of the work is probably in Part 2, not Part 1, so if you have more time to work on Part 1 than Part 2, you should probably go further ahead. In my mind, the part of the assignment I have allocated to Part 1 is a “bare minimum” to keep you from being overburdened later.

I am also supplying two test files, named tests_1.py and tests_2.py, designed to be run through pytest. They do not comprehensively test if the program works perfectly, because they don’t test your main, but they do test the LunarLander class – this may help you get your code closer to correct.

5. Exemplary

If you complete the above functionality, you should feel proud and good about yourself that you have gotten this far, and feel free to stop here! If you want to try to go for the E grade, copy your code to another file called multiplayer.py. In that file, create an alternative version of main that is very similar to the one you’ve just created, but has two LunarLander objects descending to the moon, each controlled by different users. The two players alternate back and forth entering thrust for their own landers, until one them lands or until they both crash. I’m leaving the specifications of this fairly vague: the key point is that you need to get something working that involves two players with two landers working successfully, and does so via two Lunar Lander objects. But make sure that the one player version is working regardless in lunarlander.py.

One approach you might try in multiplayer.py is to take all of your code from your original main, move it to another function called onePlayer, and create another similar function called twoPlayer. Your main function can then ask the user whether it should be a one or two player game.

6. Hints and suggestions

  • Landing without crashing is tricky. To test your program, make the initial altitude smaller and the initial fuel amount bigger. This makes the game quicker to play and easier to win.
  • Any numbers that you see scattered throughout this assignment that are not used for initializing the lander (gravity increases velocity by 2 meters/second, 4 meters/second or less to land successfully, etc.) should be stored as instance variables in your program.
  • It is useful to be able to automatically exit the program, rather than having to wait until a successful land or crash. Set up your program so that if the player enters -1 for thrust, the game automatically ends. (The function exit() can be used to automatically exit your program.)

7. Sample simulation

Welcome to Lunar Lander!

Alt = 1000 Vel = 40 Fuel = 25
How much thrust this round? 0
Alt = 958 Vel = 42 Fuel = 25
How much thrust this round? 0
Alt = 914 Vel = 44 Fuel = 25
How much thrust this round? 0
Alt = 868 Vel = 46 Fuel = 25
How much thrust this round? 0
Alt = 820 Vel = 48 Fuel = 25
How much thrust this round? 0
Alt = 770 Vel = 50 Fuel = 25
How much thrust this round? 0
Alt = 718 Vel = 52 Fuel = 25
How much thrust this round? 0
Alt = 664 Vel = 54 Fuel = 25
How much thrust this round? 0
Alt = 608 Vel = 56 Fuel = 25
How much thrust this round? 0
Alt = 550 Vel = 58 Fuel = 25
How much thrust this round? 0
Alt = 490 Vel = 60 Fuel = 25
How much thrust this round? 0
Alt = 428 Vel = 62 Fuel = 25
How much thrust this round? 0
Alt = 364 Vel = 64 Fuel = 25
How much thrust this round? 0
Alt = 298 Vel = 66 Fuel = 25
How much thrust this round? 0
Alt = 230 Vel = 68 Fuel = 25
How much thrust this round? 0
Alt = 160 Vel = 70 Fuel = 25
How much thrust this round? 2
Alt = 96 Vel = 64 Fuel = 23
How much thrust this round? 0
Alt = 30 Vel = 66 Fuel = 23
How much thrust this round? 0
Alt = -38 Vel = 68 Fuel = 23
Oh no, you crashed!

8. Grading

8.1. Part 1

You will receive an M for this assignment if…

  • when we run pytest tests_1.py, your program passes the tests.
  • you have put code in main that creates a LunarLander object, and calls its methods in some way.
  • your program is written to work in general, and not to only work for the specific tests that we have provided.

You will receive a grade of E for this assignment if you satisfy the above M requirements, and …

  • your programs have a comment at the top of each method with at least 5 words describing what the function does.
  • every one of your variable names is meaningful in some way. (Names such as thing, number, etc. are not meaningful.)
  • You have at least one other comment near what you think is the trickiest part of your code, describing how it works
  • your code demonstrates a clear sequence of actions to achieve the goal at hand, and each piece is essential. Your code does not have notably more cases or conditions than it needs to.
  • Your main has created two lunar lander objects, and you call methods on each

8.2. Part 2

You will receive an M for this assignment if…

  • when we run pytest tests_2.py, your program passes the tests.
  • when we run python lunarlander.py, we can successfully play the game with output that matches the above, but also with other inputs that correctly follow specifications.
  • your program is written to work in general, and not to only work for the specific tests that we have provided.

You will receive a grade of E for this assignment if you satisfy the above M requirements, and …

  • your programs have a comment at the top of each method with at least 5 words describing what the function does.
  • every one of your variable names is meaningful in some way. (Names such as thing, number, etc. are not meaningful.)
  • You have at least one other comment near what you think is the trickiest part of your code, describing how it works
  • your code demonstrates a clear sequence of actions to achieve the goal at hand, and each piece is essential. Your code does not have notably more cases or conditions than it needs to.
  • you have successfully made the entire game work for two lunar lander objects

9. Submit your work

When finished, zip up your code and submit your work through Moodle.

Good luck, and have fun! Remember that lab assistants are available to help out if you need it, and you can attend prefect sessions as well.

Author: Dave Musicant